home *** CD-ROM | disk | FTP | other *** search
- Subject: v07i071: Public-domain MAKE
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: caret@fairlight.oz
- Mod.sources: Volume 7, Issue 71
- Archive-name: make
-
- [ This seems to be fairly complete for the V7 make. People with
- source licenses will appreciate the appearance of this code. --r$ ]
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- # If all goes well, you will see the message "No problems found."
-
- # Exit status; set to 1 on "wc" errors or if would overwrite.
- STATUS=0
- # Contents: README Makefile h.h check.c input.c macro.c main.c
- # make.c reader.c rules.c
-
- echo x - README
- if test -f README ; then
- echo README exists, putting output in $$README
- OUT=$$README
- STATUS=1
- else
- OUT=README
- fi
- sed 's/^X//' > $OUT <<'@//E*O*F README//'
- XFollowing is a repost of the public domain 'make' that I posted
- Xto net.sources a couple of months ago. I have fixed a few bugs, and
- Xadded some more features, and the resulting changes amounted to
- Xabout as much text as the whole program (hence the repost).
-
- XFor those that missed the net.sources posting, this is a public domain
- Xre-implementation of the UNIX make program. There is no manual included;
- Xfor documentation, refer to a UNIX manual, or the source.
-
- XHere is a list of the changes made:
-
- Xi) If '-' (ignore) or '@' (silent) where used at the start
- X of a command, their effect was not turned off for the following
- X commands.
- Xii) A special target (.SUFFIXES, .PRECIOUS) or a rule (.c.o, .a.o),
- X if first in the file would be taken as the default target.
- X This resulted in error messages like "Don't know how to
- X make .c", because things like .SUFFIXES were being made.
- X This was further complicated by ---
- Xiii) Special target lines with no dependents (ie. .SUFFIXES:\n)
- X were not clearing out the existing dependents like
- X they should.
- Xiv) Default rules could not be redefined because of the error
- X checking for commands being defined twice. Now you are
- X allowed to define a target beinging with '.', having
- X no dependents with commands.
- Xv) The -q option didn't do the time comparison correctly,
- X or clear the variable used to keep track of this. Thus
- X it didn't work very well.
- Xvi) The syntax ${..} for macro's supported by UNIX make was
- X not supported.
- Xvii) There wuz a couple of spelling errors.
- Xviii) When make checked for implicit rules on targets without
- X a suffix, there were problems. (Note: The ~ feature of
- X UNIX make wasn't and still isn't supported)
- Xix) The -n option did not print @ lines like it was supposed to.
- Xx) :: added. (See UNIX manual)
- Xxi) $? added. (see UNIX manual)
- @//E*O*F README//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - Makefile
- if test -f Makefile ; then
- echo Makefile exists, putting output in $$Makefile
- OUT=$$Makefile
- STATUS=1
- else
- OUT=Makefile
- fi
- sed 's/^X//' > $OUT <<'@//E*O*F Makefile//'
- X# Makefile for make!
-
-
-
- XOBJS = check.o input.o macro.o main.o \
- X make.o reader.o rules.o
-
- Xm: $(OBJS)
- X cc -o m $(OBJS)
-
- X$(OBJS): h.h
- @//E*O*F Makefile//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - h.h
- if test -f h.h ; then
- echo h.h exists, putting output in $$h.h
- OUT=$$h.h
- STATUS=1
- else
- OUT=h.h
- fi
- sed 's/^X//' > $OUT <<'@//E*O*F h.h//'
- X/*
- X * Include header for make
- X */
-
-
- X#ifndef uchar
- X#ifdef os9
- X#define uchar char
- X#define void int
- X#define fputc putc
- X#else
- X#define uchar unsigned char
- X#endif
- X#endif
-
- X#define bool uchar
- X#define time_t long
- X#define TRUE (1)
- X#define FALSE (0)
- X#define max(a,b) ((a)>(b)?(a):(b))
-
- X#define DEFN1 "makefile" /* Default names */
- X#ifdef unix
- X#define DEFN2 "Makefile"
- X#endif
- X#ifdef eon
- X#define DEFN2 "Makefile"
- X#endif
- X/* os9 is case insensitive */
-
- X#define LZ (1024) /* Line size */
-
-
-
- X/*
- X * A name. This represents a file, either to be made, or existant
- X */
-
- Xstruct name
- X{
- X struct name * n_next; /* Next in the list of names */
- X char * n_name; /* Called */
- X struct line * n_line; /* Dependencies */
- X time_t n_time; /* Modify time of this name */
- X uchar n_flag; /* Info about the name */
- X};
-
- X#define N_MARK 0x01 /* For cycle check */
- X#define N_DONE 0x02 /* Name looked at */
- X#define N_TARG 0x04 /* Name is a target */
- X#define N_PREC 0x08 /* Target is precious */
- X#define N_DOUBLE 0x10 /* Double colon target */
-
- X/*
- X * Definition of a target line.
- X */
- Xstruct line
- X{
- X struct line * l_next; /* Next line (for ::) */
- X struct depend * l_dep; /* Dependents for this line */
- X struct cmd * l_cmd; /* Commands for this line */
- X};
-
-
- X/*
- X * List of dependents for a line
- X */
- Xstruct depend
- X{
- X struct depend * d_next; /* Next dependent */
- X struct name * d_name; /* Name of dependent */
- X};
-
-
- X/*
- X * Commands for a line
- X */
- Xstruct cmd
- X{
- X struct cmd * c_next; /* Next command line */
- X char * c_cmd; /* Command line */
- X};
-
-
- X/*
- X * Macro storage
- X */
- Xstruct macro
- X{
- X struct macro * m_next; /* Next variable */
- X char * m_name; /* Called ... */
- X char * m_val; /* Its value */
- X uchar m_flag; /* Infinite loop check */
- X};
-
- Xextern char * myname;
- Xextern struct name namehead;
- Xextern struct macro * macrohead;
- Xextern struct name * firstname;
- Xextern bool silent;
- Xextern bool ignore;
- Xextern bool rules;
- Xextern bool dotouch;
- Xextern bool quest;
- Xextern bool domake;
- Xextern char str1[];
- Xextern char str2[];
- Xextern int lineno;
-
- Xchar * fgets();
- Xchar * index();
- Xchar * rindex();
- Xchar * malloc();
- Xextern int errno;
-
- Xchar * getmacro();
- Xstruct macro * setmacro();
- Xvoid input();
- Xvoid error();
- Xvoid fatal();
- Xint make();
- Xstruct name * newname();
- Xstruct depend * newdep();
- Xstruct cmd * newcmd();
- Xvoid newline();
- Xchar * suffix();
- Xvoid touch();
- Xvoid makerules();
- Xchar * gettok();
- Xvoid precious();
- @//E*O*F h.h//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - check.c
- if test -f check.c ; then
- echo check.c exists, putting output in $$check.c
- OUT=$$check.c
- STATUS=1
- else
- OUT=check.c
- fi
- sed 's/^X//' > $OUT <<'@//E*O*F check.c//'
- X/*
- X * Check structures for make.
- X */
-
- X#include <stdio.h>
- X#include "h.h"
-
-
- X/*
- X * Prints out the structures as defined in memory. Good for check
- X * that you make file does what you want (and for debugging make).
- X */
- Xvoid
- Xprt()
- X{
- X register struct name * np;
- X register struct depend * dp;
- X register struct line * lp;
- X register struct cmd * cp;
- X register struct macro * mp;
-
-
- X for (mp = macrohead; mp; mp = mp->m_next)
- X fprintf(stderr, "%s = %s\n", mp->m_name, mp->m_val);
-
- X fputc('\n', stderr);
-
- X for (np = namehead.n_next; np; np = np->n_next)
- X {
- X if (np->n_flag & N_DOUBLE)
- X fprintf(stderr, "%s::\n", np->n_name);
- X else
- X fprintf(stderr, "%s:\n", np->n_name);
- X if (np == firstname)
- X fprintf(stderr, "(MAIN NAME)\n");
- X for (lp = np->n_line; lp; lp = lp->l_next)
- X {
- X fputc(':', stderr);
- X for (dp = lp->l_dep; dp; dp = dp->d_next)
- X fprintf(stderr, " %s", dp->d_name->n_name);
- X fputc('\n', stderr);
-
- X for (cp = lp->l_cmd; cp; cp = cp->c_next)
- X#ifdef os9
- X fprintf(stderr, "- %s\n", cp->c_cmd);
- X#else
- X fprintf(stderr, "-\t%s\n", cp->c_cmd);
- X#endif
- X fputc('\n', stderr);
- X }
- X fputc('\n', stderr);
- X }
- X}
-
-
- X/*
- X * Recursive routine that does the actual checking.
- X */
- Xvoid
- Xcheck(np)
- Xstruct name * np;
- X{
- X register struct depend * dp;
- X register struct line * lp;
-
-
- X if (np->n_flag & N_MARK)
- X fatal("Circular dependency from %s", np->n_name);
-
- X np->n_flag |= N_MARK;
-
- X for (lp = np->n_line; lp; lp = lp->l_next)
- X for (dp = lp->l_dep; dp; dp = dp->d_next)
- X check(dp->d_name);
-
- X np->n_flag &= ~N_MARK;
- X}
-
-
- X/*
- X * Look for circular dependancies.
- X * ie.
- X * a: b
- X * b: a
- X * is a circular dep
- X */
- Xvoid
- Xcirch()
- X{
- X register struct name * np;
-
-
- X for (np = namehead.n_next; np; np = np->n_next)
- X check(np);
- X}
-
-
- X/*
- X * Check the target .PRECIOUS, and mark its dependentd as precious
- X */
- Xvoid
- Xprecious()
- X{
- X register struct depend * dp;
- X register struct line * lp;
- X register struct name * np;
-
-
- X if (!((np = newname(".PRECIOUS"))->n_flag & N_TARG))
- X return;
-
- X for (lp = np->n_line; lp; lp = lp->l_next)
- X for (dp = lp->l_dep; dp; dp = dp->d_next)
- X dp->d_name->n_flag |= N_PREC;
- X}
- @//E*O*F check.c//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - input.c
- if test -f input.c ; then
- echo input.c exists, putting output in $$input.c
- OUT=$$input.c
- STATUS=1
- else
- OUT=input.c
- fi
- sed 's/^X//' > $OUT <<'@//E*O*F input.c//'
- X/*
- X * Parse a makefile
- X */
-
-
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "h.h"
-
-
- Xstruct name namehead;
- Xstruct name * firstname;
-
- Xchar str1[LZ]; /* General store */
- Xchar str2[LZ];
-
-
- X/*
- X * Intern a name. Return a pointer to the name struct
- X */
- Xstruct name *
- Xnewname(name)
- Xchar * name;
- X{
- X register struct name * rp;
- X register struct name * rrp;
- X register char * cp;
-
-
- X for
- X (
- X rp = namehead.n_next, rrp = &namehead;
- X rp;
- X rp = rp->n_next, rrp = rrp->n_next
- X )
- X if (strcmp(name, rp->n_name) == 0)
- X return rp;
-
- X if ((rp = (struct name *)malloc(sizeof (struct name)))
- X == (struct name *)0)
- X fatal("No memory for name");
- X rrp->n_next = rp;
- X rp->n_next = (struct name *)0;
- X if ((cp = malloc(strlen(name)+1)) == (char *)0)
- X fatal("No memory for name");
- X strcpy(cp, name);
- X rp->n_name = cp;
- X rp->n_line = (struct line *)0;
- X rp->n_time = (time_t)0;
- X rp->n_flag = 0;
-
- X return rp;
- X}
-
-
- X/*
- X * Add a dependant to the end of the supplied list of dependants.
- X * Return the new head pointer for that list.
- X */
- Xstruct depend *
- Xnewdep(np, dp)
- Xstruct name * np;
- Xstruct depend * dp;
- X{
- X register struct depend * rp;
- X register struct depend * rrp;
-
-
- X if ((rp = (struct depend *)malloc(sizeof (struct depend)))
- X == (struct depend *)0)
- X fatal("No memory for dependant");
- X rp->d_next = (struct depend *)0;
- X rp->d_name = np;
-
- X if (dp == (struct depend *)0)
- X return rp;
-
- X for (rrp = dp; rrp->d_next; rrp = rrp->d_next)
- X ;
-
- X rrp->d_next = rp;
-
- X return dp;
- X}
-
-
- X/*
- X * Add a command to the end of the supplied list of commands.
- X * Return the new head pointer for that list.
- X */
- Xstruct cmd *
- Xnewcmd(str, cp)
- Xchar * str;
- Xstruct cmd * cp;
- X{
- X register struct cmd * rp;
- X register struct cmd * rrp;
- X register char * rcp;
-
-
- X if (rcp = rindex(str, '\n'))
- X *rcp = '\0'; /* Loose newline */
-
- X while (isspace(*str))
- X str++;
-
- X if (*str == '\0') /* If nothing left, the exit */
- X return;
-
- X if ((rp = (struct cmd *)malloc(sizeof (struct cmd)))
- X == (struct cmd *)0)
- X fatal("No memory for command");
- X rp->c_next = (struct cmd *)0;
- X if ((rcp = malloc(strlen(str)+1)) == (char *)0)
- X fatal("No memory for command");
- X strcpy(rcp, str);
- X rp->c_cmd = rcp;
-
- X if (cp == (struct cmd *)0)
- X return rp;
-
- X for (rrp = cp; rrp->c_next; rrp = rrp->c_next)
- X ;
-
- X rrp->c_next = rp;
-
- X return cp;
- X}
-
-
- X/*
- X * Add a new 'line' of stuff to a target. This check to see
- X * if commands already exist for the target. If flag is set,
- X * the line is a double colon target.
- X *
- X * Kludges:
- X * i) If the new name begins with a '.', and there are no dependents,
- X * then the target must cease to be a target. This is for .SUFFIXES.
- X * ii) If the new name begins with a '.', with no dependents and has
- X * commands, then replace the current commands. This is for
- X * redefining commands for a default rule.
- X * Neither of these free the space used by dependents or commands,
- X * since they could be used by another target.
- X */
- Xvoid
- Xnewline(np, dp, cp, flag)
- Xstruct name * np;
- Xstruct depend * dp;
- Xstruct cmd * cp;
- X{
- X bool hascmds = FALSE; /* Target has commands */
- X register struct line * rp;
- X register struct line * rrp;
-
-
- X /* Handle the .SUFFIXES case */
- X if (np->n_name[0] == '.' && !dp && !cp)
- X {
- X for (rp = np->n_line; rp; rp = rrp)
- X {
- X rrp = rp->l_next;
- X free(rp);
- X }
- X np->n_line = (struct line *)0;
- X np->n_flag &= ~N_TARG;
- X return;
- X }
-
- X /* This loop must happen since rrp is used later. */
- X for
- X (
- X rp = np->n_line, rrp = (struct line *)0;
- X rp;
- X rrp = rp, rp = rp->l_next
- X )
- X if (rp->l_cmd)
- X hascmds = TRUE;
-
- X if (hascmds && cp && !(np->n_flag & N_DOUBLE))
- X /* Handle the implicit rules redefinition case */
- X if (np->n_name[0] == '.' && dp == (struct depend *)0)
- X {
- X np->n_line->l_cmd = cp;
- X return;
- X }
- X else
- X error("Commands defined twice for target %s", np->n_name);
- X if (np->n_flag & N_TARG)
- X if (!(np->n_flag & N_DOUBLE) != !flag) /* like xor */
- X error("Inconsistent rules for target %s", np->n_name);
-
- X if ((rp = (struct line *)malloc(sizeof (struct line)))
- X == (struct line *)0)
- X fatal("No memory for line");
- X rp->l_next = (struct line *)0;
- X rp->l_dep = dp;
- X rp->l_cmd = cp;
-
- X if (rrp)
- X rrp->l_next = rp;
- X else
- X np->n_line = rp;
-
- X np->n_flag |= N_TARG;
- X if (flag)
- X np->n_flag |= N_DOUBLE;
- X}
-
-
- X/*
- X * Parse input from the makefile, and construct a tree structure
- X * of it.
- X */
- Xvoid
- Xinput(fd)
- XFILE * fd;
- X{
- X char * p; /* General */
- X char * q;
- X struct name * np;
- X struct depend * dp;
- X struct cmd * cp;
- X bool dbl;
-
-
- X if (getline(str1, fd)) /* Read the first line */
- X return;
-
- X for(;;)
- X {
- X#ifdef os9
- X if (*str1 == ' ') /* Rules without targets */
- X#else
- X if (*str1 == '\t') /* Rules without targets */
- X#endif
- X error("Rules not allowed here");
-
- X p = str1;
-
- X while (isspace(*p)) /* Find first target */
- X p++;
-
- X while (((q = index(p, '=')) != (char *)0) &&
- X (p != q) && (q[-1] == '\\')) /* Find value */
- X {
- X register char * a;
-
- X a = q - 1; /* Del \ chr; move rest back */
- X p = q;
- X while(*a++ = *q++)
- X ;
- X }
-
- X if (q != (char *)0)
- X {
- X register char * a;
-
- X *q++ = '\0'; /* Separate name and val */
- X while (isspace(*q))
- X q++;
- X if (p = rindex(q, '\n'))
- X *p = '\0';
-
- X p = str1;
- X if ((a = gettok(&p)) == (char *)0)
- X error("No macro name");
-
- X setmacro(a, q);
-
- X if (getline(str1, fd))
- X return;
- X continue;
- X }
-
- X expand(str1);
- X p = str1;
-
- X while (((q = index(p, ':')) != (char *)0) &&
- X (p != q) && (q[-1] == '\\')) /* Find dependents */
- X {
- X register char * a;
-
- X a = q - 1; /* Del \ chr; move rest back */
- X p = q;
- X while(*a++ = *q++)
- X ;
- X }
-
- X if (q == (char *)0)
- X error("No targets provided");
-
- X *q++ = '\0'; /* Separate targets and dependents */
-
- X if (*q == ':') /* Double colon */
- X {
- X dbl = 1;
- X q++;
- X }
- X else
- X dbl = 0;
-
- X for (dp = (struct depend *)0; ((p = gettok(&q)) != (char *)0);)
- X /* get list of dep's */
- X {
- X np = newname(p); /* Intern name */
- X dp = newdep(np, dp); /* Add to dep list */
- X }
-
- X *((q = str1) + strlen(str1) + 1) = '\0';
- X /* Need two nulls for gettok (Remember separation) */
-
- X cp = (struct cmd *)0;
- X if (getline(str2, fd) == FALSE) /* Get commands */
- X {
- X#ifdef os9
- X while (*str2 == ' ')
- X#else
- X while (*str2 == '\t')
- X#endif
- X {
- X cp = newcmd(&str2[0], cp);
- X if (getline(str2, fd))
- X break;
- X }
- X }
-
- X while ((p = gettok(&q)) != (char *)0) /* Get list of targ's */
- X {
- X np = newname(p); /* Intern name */
- X newline(np, dp, cp, dbl);
- X if (!firstname && p[0] != '.')
- X firstname = np;
- X }
-
- X if (feof(fd)) /* EOF? */
- X return;
-
- X strcpy(str1, str2);
- X }
- X}
- @//E*O*F input.c//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - macro.c
- if test -f macro.c ; then
- echo macro.c exists, putting output in $$macro.c
- OUT=$$macro.c
- STATUS=1
- else
- OUT=macro.c
- fi
- sed 's/^X//' > $OUT <<'@//E*O*F macro.c//'
- X/*
- X * Macro control for make
- X */
-
-
- X#include "h.h"
-
-
- Xstruct macro * macrohead;
-
-
- Xstruct macro *
- Xgetmp(name)
- Xchar * name;
- X{
- X register struct macro * rp;
-
- X for (rp = macrohead; rp; rp = rp->m_next)
- X if (strcmp(name, rp->m_name) == 0)
- X return rp;
- X return (struct macro *)0;
- X}
-
-
- Xchar *
- Xgetmacro(name)
- Xchar * name;
- X{
- X struct macro * mp;
-
- X if (mp = getmp(name))
- X return mp->m_val;
- X else
- X return "";
- X}
-
-
- Xstruct macro *
- Xsetmacro(name, val)
- Xchar * name;
- Xchar * val;
- X{
- X register struct macro * rp;
- X register char * cp;
-
-
- X /* Replace macro definition if it exists */
- X for (rp = macrohead; rp; rp = rp->m_next)
- X if (strcmp(name, rp->m_name) == 0)
- X {
- X free(rp->m_val); /* Free space from old */
- X break;
- X }
-
- X if (!rp) /* If not defined, allocate space for new */
- X {
- X if ((rp = (struct macro *)malloc(sizeof (struct macro)))
- X == (struct macro *)0)
- X fatal("No memory for macro");
-
- X rp->m_next = macrohead;
- X macrohead = rp;
- X rp->m_flag = FALSE;
-
- X if ((cp = malloc(strlen(name)+1)) == (char *)0)
- X fatal("No memory for macro");
- X strcpy(cp, name);
- X rp->m_name = cp;
- X }
-
- X if ((cp = malloc(strlen(val)+1)) == (char *)0)
- X fatal("No memory for macro");
- X strcpy(cp, val); /* Copy in new value */
- X rp->m_val = cp;
-
- X return rp;
- X}
-
-
- X/*
- X * Do the dirty work for expand
- X */
- Xvoid
- Xdoexp(to, from, len, buf)
- Xchar ** to;
- Xchar * from;
- Xint * len;
- Xchar * buf;
- X{
- X register char * rp;
- X register char * p;
- X register char * q;
- X register struct macro * mp;
-
-
- X rp = from;
- X p = *to;
- X while (*rp)
- X {
- X if (*rp != '$')
- X {
- X *p++ = *rp++;
- X (*len)--;
- X }
- X else
- X {
- X q = buf;
- X if (*++rp == '{')
- X while (*++rp && *rp != '}')
- X *q++ = *rp;
- X else if (*rp == '(')
- X while (*++rp && *rp != ')')
- X *q++ = *rp;
- X else if (!*rp)
- X {
- X *p++ = '$';
- X break;
- X }
- X else
- X *q++ = *rp;
- X *q = '\0';
- X if (*rp)
- X rp++;
- X if (!(mp = getmp(buf)))
- X mp = setmacro(buf, "");
- X if (mp->m_flag)
- X fatal("Infinitely recursive macro %s", mp->m_name);
- X mp->m_flag = TRUE;
- X *to = p;
- X doexp(to, mp->m_val, len, buf);
- X p = *to;
- X mp->m_flag = FALSE;
- X }
- X if (*len <= 0)
- X error("Expanded line too line");
- X }
- X *p = '\0';
- X *to = p;
- X}
-
-
- X/*
- X * Expand any macros in str.
- X */
- Xvoid
- Xexpand(str)
- Xchar * str;
- X{
- X static char a[LZ];
- X static char b[LZ];
- X char * p = str;
- X int len = LZ-1;
-
- X strcpy(a, str);
- X doexp(&p, a, &len, b);
- X}
- @//E*O*F macro.c//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - main.c
- if test -f main.c ; then
- echo main.c exists, putting output in $$main.c
- OUT=$$main.c
- STATUS=1
- else
- OUT=main.c
- fi
- sed 's/^X//' > $OUT <<'@//E*O*F main.c//'
- X/*
- X * make [-f makefile] [-ins] [target(s) ...]
- X *
- X * (Better than EON mk but not quite as good as UNIX make)
- X *
- X * -f makefile name
- X * -i ignore exit status
- X * -n Pretend to make
- X * -p Print all macros & targets
- X * -q Question up-to-dateness of target. Return exit status 1 if not
- X * -r Don't not use inbuilt rules
- X * -s Make silently
- X * -t Touch files instead of making them
- X * -m Change memory requirements (EON only)
- X */
-
- X#include <stdio.h>
- X#include "h.h"
-
- X#ifdef unix
- X#include <sys/errno.h>
- X#endif
- X#ifdef eon
- X#include <sys/err.h>
- X#endif
- X#ifdef os9
- X#include <errno.h>
- X#endif
-
-
- X#ifdef eon
- X#define MEMSPACE (16384)
- X#endif
-
-
- Xchar * myname;
- Xchar * makefile; /* The make file */
- X#ifdef eon
- Xunsigned memspace = MEMSPACE;
- X#endif
-
- XFILE * ifd; /* Input file desciptor */
- Xbool domake = TRUE; /* Go through the motions option */
- Xbool ignore = FALSE; /* Ignore exit status option */
- Xbool silent = FALSE; /* Silent option */
- Xbool print = FALSE; /* Print debuging information */
- Xbool rules = TRUE; /* Use inbuilt rules */
- Xbool dotouch = FALSE;/* Touch files instead of making */
- Xbool quest = FALSE; /* Question up-to-dateness of file */
-
-
- Xvoid
- Xmain(argc, argv)
- Xint argc;
- Xchar ** argv;
- X{
- X register char * p; /* For argument processing */
- X int estat = 0; /* For question */
- X register struct name * np;
-
-
- X myname = (argc-- < 1) ? "make" : *argv++;
-
- X while ((argc > 0) && (**argv == '-'))
- X {
- X argc--; /* One less to process */
- X p = *argv++; /* Now processing this one */
-
- X while (*++p != '\0')
- X {
- X switch(*p)
- X {
- X case 'f': /* Alternate file name */
- X if (*++p == '\0')
- X {
- X if (argc-- <= 0)
- X usage();
- X p = *argv++;
- X }
- X makefile = p;
- X goto end_of_args;
- X#ifdef eon
- X case 'm': /* Change space requirements */
- X if (*++p == '\0')
- X {
- X if (argc-- <= 0)
- X usage();
- X p = *argv++;
- X }
- X memspace = atoi(p);
- X goto end_of_args;
- X#endif
- X case 'n': /* Pretend mode */
- X domake = FALSE;
- X break;
- X case 'i': /* Ignore fault mode */
- X ignore = TRUE;
- X break;
- X case 's': /* Silent about commands */
- X silent = TRUE;
- X break;
- X case 'p':
- X print = TRUE;
- X break;
- X case 'r':
- X rules = FALSE;
- X break;
- X case 't':
- X dotouch = TRUE;
- X break;
- X case 'q':
- X quest = TRUE;
- X break;
- X default: /* Wrong option */
- X usage();
- X }
- X }
- X end_of_args:;
- X }
-
- X#ifdef eon
- X if (initalloc(memspace) == 0xffff) /* Must get memory for alloc */
- X fatal("Cannot initalloc memory");
- X#endif
-
- X if (strcmp(makefile, "-") == 0) /* Can use stdin as makefile */
- X ifd = stdin;
- X else
- X if (!makefile) /* If no file, then use default */
- X {
- X if ((ifd = fopen(DEFN1, "r")) == (FILE *)0)
- X#ifdef eon
- X if (errno != ER_NOTF)
- X fatal("Can't open %s; error %02x", DEFN1, errno);
- X#endif
- X#ifdef unix
- X if (errno != ENOENT)
- X fatal("Can't open %s; error %02x", DEFN1, errno);
- X#endif
- X#ifndef os9
- X if ((ifd == (FILE *)0)
- X && ((ifd = fopen(DEFN2, "r")) == (FILE *)0))
- X fatal("Can't open %s", DEFN2);
- X#else
- X fatal("Can't open %s", DEFN1);
- X#endif
- X }
- X else
- X if ((ifd = fopen(makefile, "r")) == (FILE *)0)
- X fatal("Can't open %s", makefile);
-
- X makerules();
-
- X setmacro("$", "$");
-
- X while (argc && (p = index(*argv, '=')))
- X {
- X char c;
-
- X c = *p;
- X *p = '\0';
- X setmacro(*argv, p+1);
- X *p = c;
-
- X argv++;
- X argc--;
- X }
-
- X input(ifd); /* Input all the gunga */
- X fclose(ifd); /* Finished with makefile */
- X lineno = 0; /* Any calls to error now print no line number */
-
- X if (print)
- X prt(); /* Print out structures */
-
- X np = newname(".SILENT");
- X if (np->n_flag & N_TARG)
- X silent = TRUE;
-
- X np = newname(".IGNORE");
- X if (np->n_flag & N_TARG)
- X ignore = TRUE;
-
- X precious();
-
- X if (!firstname)
- X fatal("No targets defined");
-
- X circh(); /* Check circles in target definitions */
-
- X if (!argc)
- X estat = make(firstname, 0);
- X else while (argc--)
- X {
- X if (!print && !silent && strcmp(*argv, "love") == 0)
- X printf("Not war!\n");
- X estat |= make(newname(*argv++), 0);
- X }
-
- X if (quest)
- X exit(estat);
- X else
- X exit(0);
- X}
-
-
- Xusage()
- X{
- X fprintf(stderr, "Usage: %s [-f makefile] [-inpqrst] [macro=val ...] [target(s) ...]\n", myname);
- X exit(1);
- X}
-
-
- Xvoid
- Xfatal(msg, a1, a2, a3, a4, a5, a6)
- Xchar *msg;
- X{
- X fprintf(stderr, "%s: ", myname);
- X fprintf(stderr, msg, a1, a2, a3, a4, a5, a6);
- X fputc('\n', stderr);
- X exit(1);
- X}
- @//E*O*F main.c//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - make.c
- if test -f make.c ; then
- echo make.c exists, putting output in $$make.c
- OUT=$$make.c
- STATUS=1
- else
- OUT=make.c
- fi
- sed 's/^X//' > $OUT <<'@//E*O*F make.c//'
- X/*
- X * Do the actual making for make
- X */
-
- X#include <stdio.h>
- X#ifdef unix
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/errno.h>
- X#endif
- X#ifdef eon
- X#include <sys/stat.h>
- X#include <sys/err.h>
- X#endif
- X#ifdef os9
- X#include <time.h>
- X#include <os9.h>
- X#include <modes.h>
- X#include <direct.h>
- X#include <errno.h>
- X#endif
- X#include "h.h"
-
-
-
- X/*
- X * Exec a shell that returns exit status correctly (/bin/esh).
- X * The standard EON shell returns the process number of the last
- X * async command, used by the debugger (ugg).
- X * [exec on eon is like a fork+exec on unix]
- X */
- Xint
- Xdosh(string, shell)
- Xchar * string;
- Xchar * shell;
- X{
- X int number;
-
- X#ifdef unix
- X return system(string);
- X#endif
- X#ifdef eon
- X return ((number = execl(shell, shell,"-c", string, 0)) == -1) ?
- X -1: /* couldn't start the shell */
- X wait(number); /* return its exit status */
- X#endif
- X#ifdef os9
- X int status, pid;
-
- X strcat(string, "\n");
- X if ((number = os9fork(shell, strlen(string), string, 0, 0, 0)) == -1)
- X return -1; /* Couldn't start a shell */
- X do
- X {
- X if ((pid = wait(&status)) == -1)
- X return -1; /* child already died!?!? */
- X } while (pid != number);
-
- X return status;
- X#endif
- X}
-
-
- X/*
- X * Do commands to make a target
- X */
- Xvoid
- Xdocmds1(np, lp)
- Xstruct name * np;
- Xstruct line * lp;
- X{
- X bool ssilent;
- X bool signore;
- X int estat;
- X register char * q;
- X register char * p;
- X char * shell;
- X register struct cmd * cp;
-
-
- X if (*(shell = getmacro("SHELL")) == '\0')
- X#ifdef eon
- X shell = ":bin/esh";
- X#endif
- X#ifdef unix
- X shell = "/bin/sh";
- X#endif
- X#ifdef os9
- X shell = "shell";
- X#endif
-
- X for (cp = lp->l_cmd; cp; cp = cp->c_next)
- X {
- X strcpy(str1, cp->c_cmd);
- X expand(str1);
- X q = str1;
- X ssilent = silent;
- X signore = ignore;
- X while ((*q == '@') || (*q == '-'))
- X {
- X if (*q == '@') /* Specific silent */
- X ssilent = TRUE;
- X else /* Specific ignore */
- X signore = TRUE;
- X q++; /* Not part of the command */
- X }
-
- X if (!domake)
- X ssilent = 0;
-
- X if (!ssilent)
- X fputs(" ", stdout);
-
- X for (p=q; *p; p++)
- X {
- X if (*p == '\n' && p[1] != '\0')
- X {
- X *p = ' ';
- X if (!ssilent)
- X fputs("\\\n", stdout);
- X }
- X else if (!ssilent)
- X putchar(*p);
- X }
- X if (!ssilent)
- X putchar('\n');
-
- X if (domake)
- X { /* Get the shell to execute it */
- X if ((estat = dosh(q, shell)) != 0)
- X {
- X if (estat == -1)
- X fatal("Couldn't execute %s", shell);
- X else
- X {
- X printf("%s: Error code %d", myname, estat);
- X if (signore)
- X fputs(" (Ignored)\n", stdout);
- X else
- X {
- X putchar('\n');
- X if (!(np->n_flag & N_PREC))
- X if (unlink(np->n_name) == 0)
- X printf("%s: '%s' removed.\n", myname, np->n_name);
- X exit(estat);
- X }
- X }
- X }
- X }
- X }
- X}
-
-
- Xdocmds(np)
- Xstruct name * np;
- X{
- X register struct line * lp;
-
-
- X for (lp = np->n_line; lp; lp = lp->l_next)
- X docmds1(np, lp);
- X}
-
-
- X#ifdef os9
- X/*
- X * Some stuffing around to get the modified time of a file
- X * in an os9 file system
- X */
- Xgetmdate(fd, tbp)
- Xstruct sgtbuf * tbp;
- X{
- X struct registers regs;
- X static struct fildes fdbuf;
-
-
- X regs.rg_a = fd;
- X regs.rg_b = SS_FD;
- X regs.rg_x = &fdbuf;
- X regs.rg_y = sizeof (fdbuf);
-
- X if (_os9(I_GETSTT, ®s) == -1)
- X {
- X errno = regs.rg_b & 0xff;
- X return -1;
- X }
- X if (tbp)
- X {
- X _strass(tbp, fdbuf.fd_date, sizeof (fdbuf.fd_date));
- X tbp->t_second = 0; /* Files are only acurate to mins */
- X }
- X return 0;
- X}
-
-
- X/*
- X * Kludge routine to return an aproximation of how many
- X * seconds since 1980. Dates will be in order, but will not
- X * be lineer
- X */
- Xtime_t
- Xcnvtime(tbp)
- Xstruct sgtbuf *tbp;
- X{
- X long acc;
-
-
- X acc = tbp->t_year - 80; /* Baseyear is 1980 */
- X acc = acc * 12 + tbp->t_month;
- X acc = acc * 31 + tbp->t_day;
- X acc = acc * 24 + tbp->t_hour;
- X acc = acc * 60 + tbp->t_minute;
- X acc = acc * 60 + tbp->t_second;
-
- X return acc;
- X}
-
-
- X/*
- X * Get the current time in the internal format
- X */
- Xtime(tp)
- Xtime_t * tp;
- X{
- X struct sgtbuf tbuf;
-
-
- X if (getime(&tbuf) < 0)
- X return -1;
-
- X if (tp)
- X *tp = cnvtime(&tbuf);
-
- X return 0;
- X}
- X#endif
-
-
- X/*
- X * Get the modification time of a file. If the first
- X * doesn't exist, it's modtime is set to 0.
- X */
- Xvoid
- Xmodtime(np)
- Xstruct name * np;
- X{
- X#ifdef unix
- X struct stat info;
- X int fd;
-
-
- X if (stat(np->n_name, &info) < 0)
- X {
- X if (errno != ENOENT)
- X fatal("Can't open %s; error %d", np->n_name, errno);
-
- X np->n_time = 0L;
- X }
- X else
- X np->n_time = info.st_mtime;
- X#endif
- X#ifdef eon
- X struct stat info;
- X int fd;
-
-
- X if ((fd = open(np->n_name, 0)) < 0)
- X {
- X if (errno != ER_NOTF)
- X fatal("Can't open %s; error %02x", np->n_name, errno);
-
- X np->n_time = 0L;
- X }
- X else if (getstat(fd, &info) < 0)
- X fatal("Can't getstat %s; error %02x", np->n_name, errno);
- X else
- X np->n_time = info.st_mod;
-
- X close(fd);
- X#endif
- X#ifdef os9
- X struct sgtbuf info;
- X int fd;
-
-
- X if ((fd = open(np->n_name, 0)) < 0)
- X {
- X if (errno != E_PNNF)
- X fatal("Can't open %s; error %02x", np->n_name, errno);
-
- X np->n_time = 0L;
- X }
- X else if (getmdate(fd, &info) < 0)
- X fatal("Can't getstat %s; error %02x", np->n_name, errno);
- X else
- X np->n_time = cnvtime(&info);
-
- X close(fd);
- X#endif
- X}
-
-
- X/*
- X * Update the mod time of a file to now.
- X */
- Xvoid
- Xtouch(np)
- Xstruct name * np;
- X{
- X char c;
- X int fd;
-
-
- X if (!domake || !silent)
- X printf(" touch(%s)\n", np->n_name);
-
- X if (domake)
- X {
- X#ifdef unix
- X long a[2];
-
- X a[0] = a[1] = time(0);
- X if (utime(np->n_name, &a[0]) < 0)
- X printf("%s: '%s' not touched - non-existant\n",
- X myname, np->n_name);
- X#endif
- X#ifdef eon
- X if ((fd = open(np->n_name, 0)) < 0)
- X printf("%s: '%s' not touched - non-existant\n",
- X myname, np->n_name);
- X else
- X {
- X uread(fd, &c, 1, 0);
- X uwrite(fd, &c, 1);
- X }
- X close(fd);
- X#endif
- X#ifdef os9
- X /*
- X * Strange that something almost as totally useless
- X * as this is easy to do in os9!
- X */
- X if ((fd = open(np->n_name, S_IWRITE)) < 0)
- X printf("%s: '%s' not touched - non-existant\n",
- X myname, np->n_name);
- X close(fd);
- X#endif
- X }
- X}
-
-
- X/*
- X * Recursive routine to make a target.
- X */
- Xint
- Xmake(np, level)
- Xstruct name * np;
- Xint level;
- X{
- X register struct depend * dp;
- X register struct line * lp;
- X register struct depend * qdp;
- X time_t dtime = 1;
- X bool didsomething = 0;
-
-
- X if (np->n_flag & N_DONE)
- X return 0;
-
- X if (!np->n_time)
- X modtime(np); /* Gets modtime of this file */
-
- X if (rules)
- X {
- X for (lp = np->n_line; lp; lp = lp->l_next)
- X if (lp->l_cmd)
- X break;
- X if (!lp)
- X dyndep(np);
- X }
-
- X if (!(np->n_flag & N_TARG) && np->n_time == 0L)
- X fatal("Don't know how to make %s", np->n_name);
-
- X for (qdp = (struct depend *)0, lp = np->n_line; lp; lp = lp->l_next)
- X {
- X for (dp = lp->l_dep; dp; dp = dp->d_next)
- X {
- X make(dp->d_name, level+1);
- X if (np->n_time < dp->d_name->n_time)
- X qdp = newdep(dp->d_name, qdp);
- X dtime = max(dtime, dp->d_name->n_time);
- X }
- X if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime))
- X {
- X make1(np, lp, qdp); /* free()'s qdp */
- X dtime = 1;
- X qdp = (struct depend *)0;
- X didsomething++;
- X }
- X }
-
- X np->n_flag |= N_DONE;
-
- X if (quest)
- X {
- X long t;
-
- X t = np->n_time;
- X time(&np->n_time);
- X return t < dtime;
- X }
- X else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE))
- X {
- X make1(np, (struct line *)0, qdp); /* free()'s qdp */
- X time(&np->n_time);
- X }
- X else if (level == 0 && !didsomething)
- X printf("%s: '%s' is up to date\n", myname, np->n_name);
- X return 0;
- X}
-
-
- Xmake1(np, lp, qdp)
- Xregister struct depend * qdp;
- Xstruct line * lp;
- Xstruct name * np;
- X{
- X register struct depend * dp;
-
-
- X if (dotouch)
- X touch(np);
- X else
- X {
- X strcpy(str1, "");
- X for (dp = qdp; dp; dp = qdp)
- X {
- X if (strlen(str1))
- X strcat(str1, " ");
- X strcat(str1, dp->d_name->n_name);
- X qdp = dp->d_next;
- X free(dp);
- X }
- X setmacro("?", str1);
- X setmacro("@", np->n_name);
- X if (lp) /* lp set if doing a :: rule */
- X docmds1(np, lp);
- X else
- X docmds(np);
- X }
- X}
- @//E*O*F make.c//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - reader.c
- if test -f reader.c ; then
- echo reader.c exists, putting output in $$reader.c
- OUT=$$reader.c
- STATUS=1
- else
- OUT=reader.c
- fi
- sed 's/^X//' > $OUT <<'@//E*O*F reader.c//'
- X/*
- X * Read in makefile
- X */
-
-
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "h.h"
-
-
- Xint lineno;
-
-
- X/*
- X * Syntax error handler. Print message, with line number, and exits.
- X */
- Xvoid
- Xerror(msg, a1, a2, a3)
- Xchar * msg;
- X{
- X fprintf(stderr, "%s: ", myname);
- X fprintf(stderr, msg, a1, a2, a3);
- X if (lineno)
- X fprintf(stderr, " near line %d", lineno);
- X fputc('\n', stderr);
- X exit(1);
- X}
-
-
- X/*
- X * Read a line into the supplied string of length LZ. Remove
- X * comments, ignore blank lines. Deal with quoted (\) #, and
- X * quoted newlines. If EOF return TRUE.
- X */
- Xbool
- Xgetline(str, fd)
- Xchar * str;
- XFILE * fd;
- X{
- X register char * p;
- X char * q;
- X int pos = 0;
-
-
- X for (;;)
- X {
- X if (fgets(str+pos, LZ-pos, fd) == (char *)0)
- X return TRUE; /* EOF */
-
- X lineno++;
-
- X if ((p = index(str+pos, '\n')) == (char *)0)
- X error("Line too long");
-
- X if (p[-1] == '\\')
- X {
- X p[-1] = '\n';
- X pos = p - str;
- X continue;
- X }
-
- X p = str;
- X while (((q = index(p, '#')) != (char *)0) &&
- X (p != q) && (q[-1] == '\\'))
- X {
- X char *a;
-
- X a = q - 1; /* Del \ chr; move rest back */
- X p = q;
- X while (*a++ = *q++)
- X ;
- X }
- X if (q != (char *)0)
- X {
- X q[0] = '\n';
- X q[1] = '\0';
- X }
-
- X p = str;
- X while (isspace(*p)) /* Checking for blank */
- X p++;
-
- X if (*p != '\0')
- X return FALSE;
- X pos = 0;
- X }
- X}
-
-
- X/*
- X * Get a word from the current line, surounded by white space.
- X * return a pointer to it. String returned has no white spaces
- X * in it.
- X */
- Xchar *
- Xgettok(ptr)
- Xchar **ptr;
- X{
- X register char * p;
-
-
- X while (isspace(**ptr)) /* Skip spaces */
- X (*ptr)++;
-
- X if (**ptr == '\0') /* Nothing after spaces */
- X return NULL;
-
- X p = *ptr; /* word starts here */
-
- X while ((**ptr != '\0') && (!isspace(**ptr)))
- X (*ptr)++; /* Find end of word */
-
- X *(*ptr)++ = '\0'; /* Terminate it */
-
- X return(p);
- X}
- @//E*O*F reader.c//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - rules.c
- if test -f rules.c ; then
- echo rules.c exists, putting output in $$rules.c
- OUT=$$rules.c
- STATUS=1
- else
- OUT=rules.c
- fi
- sed 's/^X//' > $OUT <<'@//E*O*F rules.c//'
- X/*
- X * Control of the implicit suffix rules
- X */
-
-
- X#include "h.h"
-
-
- X/*
- X * Return a pointer to the suffix of a name
- X */
- Xchar *
- Xsuffix(name)
- Xchar * name;
- X{
- X return rindex(name, '.');
- X}
-
-
- X/*
- X * Dynamic dependency. This routine applies the suffis rules
- X * to try and find a source and a set of rules for a missing
- X * target. If found, np is made into a target with the implicit
- X * source name, and rules. Returns TRUE if np was made into
- X * a target.
- X */
- Xbool
- Xdyndep(np)
- Xstruct name * np;
- X{
- X register char * p;
- X register char * q;
- X register char * suff; /* Old suffix */
- X register char * basename; /* Name without suffix */
- X struct name * op; /* New dependent */
- X struct name * sp; /* Suffix */
- X struct line * lp;
- X struct depend * dp;
- X char * newsuff;
-
-
- X p = str1;
- X q = np->n_name;
- X if (!(suff = suffix(q)))
- X return FALSE; /* No suffix */
- X while (q < suff)
- X *p++ = *q++;
- X *p = '\0';
- X basename = setmacro("*", str1)->m_val;
-
- X if (!((sp = newname(".SUFFIXES"))->n_flag & N_TARG))
- X return FALSE;
-
- X for (lp = sp->n_line; lp; lp = lp->l_next)
- X for (dp = lp->l_dep; dp; dp = dp->d_next)
- X {
- X newsuff = dp->d_name->n_name;
- X if (strlen(suff)+strlen(newsuff)+1 >= LZ)
- X fatal("Suffix rule too long");
- X p = str1;
- X q = newsuff;
- X while (*p++ = *q++)
- X ;
- X p--;
- X q = suff;
- X while (*p++ = *q++)
- X ;
- X sp = newname(str1);
- X if (sp->n_flag & N_TARG)
- X {
- X p = str1;
- X q = basename;
- X if (strlen(basename) + strlen(newsuff)+1 >= LZ)
- X fatal("Implicit name too long");
- X while (*p++ = *q++)
- X ;
- X p--;
- X q = newsuff;
- X while (*p++ = *q++)
- X ;
- X op = newname(str1);
- X if (!op->n_time)
- X modtime(op);
- X if (op->n_time)
- X {
- X dp = newdep(op, 0);
- X newline(np, dp, sp->n_line->l_cmd, 0);
- X setmacro("<", op->n_name);
- X return TRUE;
- X }
- X }
- X }
- X return FALSE;
- X}
-
-
- X/*
- X * Make the default rules
- X */
- Xvoid
- Xmakerules()
- X{
- X struct cmd * cp;
- X struct name * np;
- X struct depend * dp;
-
-
- X#ifdef eon
- X setmacro("BDSCC", "asm");
- X /* setmacro("BDSCFLAGS", ""); */
- X cp = newcmd("$(BDSCC) $(BDSCFLAGS) -n $<", 0);
- X np = newname(".c.o");
- X newline(np, 0, cp, 0);
-
- X setmacro("CC", "c");
- X setmacro("CFLAGS", "-O");
- X cp = newcmd("$(CC) $(CFLAGS) -c $<", 0);
- X np = newname(".c.obj");
- X newline(np, 0, cp, 0);
-
- X setmacro("M80", "asm -n");
- X /* setmacro("M80FLAGS", ""); */
- X cp = newcmd("$(M80) $(M80FLAGS) $<", 0);
- X np = newname(".mac.o");
- X newline(np, 0, cp, 0);
-
- X setmacro("AS", "zas");
- X /* setmacro("ASFLAGS", ""); */
- X cp = newcmd("$(ZAS) $(ASFLAGS) -o $@ $<", 0);
- X np = newname(".as.obj");
- X newline(np, 0, cp, 0);
-
- X np = newname(".as");
- X dp = newdep(np, 0);
- X np = newname(".obj");
- X dp = newdep(np, dp);
- X np = newname(".c");
- X dp = newdep(np, dp);
- X np = newname(".o");
- X dp = newdep(np, dp);
- X np = newname(".mac");
- X dp = newdep(np, dp);
- X np = newname(".SUFFIXES");
- X newline(np, dp, 0, 0);
- X#endif
-
- X/*
- X * Some of the UNIX implicit rules
- X */
- X#ifdef unix
- X setmacro("CC", "cc");
- X setmacro("CFLAGS", "-O");
- X cp = newcmd("$(CC) $(CFLAGS) -c $<", 0);
- X np = newname(".c.o");
- X newline(np, 0, cp, 0);
-
- X setmacro("AS", "as");
- X cp = newcmd("$(AS) -o $@ $<", 0);
- X np = newname(".s.o");
- X newline(np, 0, cp, 0);
-
- X setmacro("YACC", "yacc");
- X /* setmacro("YFLAGS", ""); */
- X cp = newcmd("$(YACC) $(YFLAGS) $<", 0);
- X cp = newcmd("mv y.tab.c $@", cp);
- X np = newname(".y.c");
- X newline(np, 0, cp, 0);
-
- X cp = newcmd("$(YACC) $(YFLAGS) $<", 0);
- X cp = newcmd("$(CC) $(CFLAGS) -c y.tab.c", cp);
- X cp = newcmd("rm y.tab.c", cp);
- X cp = newcmd("mv y.tab.o $@", cp);
- X np = newname(".y.o");
- X newline(np, 0, cp, 0);
-
- X np = newname(".s");
- X dp = newdep(np, 0);
- X np = newname(".o");
- X dp = newdep(np, dp);
- X np = newname(".c");
- X dp = newdep(np, dp);
- X np = newname(".y");
- X dp = newdep(np, dp);
- X np = newname(".SUFFIXES");
- X newline(np, dp, 0, 0);
- X#endif
- X#ifdef os9
- X/*
- X * Fairlight use an enhanced version of the C sub-system.
- X * They have a specialised macro pre-processor.
- X */
- X setmacro("CC", "cc");
- X setmacro("CFLAGS", "-z");
- X cp = newcmd("$(CC) $(CFLAGS) -r $<", 0);
-
- X np = newname(".c.r");
- X newline(np, 0, cp, 0);
- X np = newname(".ca.r");
- X newline(np, 0, cp, 0);
- X np = newname(".a.r");
- X newline(np, 0, cp, 0);
- X np = newname(".o.r");
- X newline(np, 0, cp, 0);
- X np = newname(".mc.r");
- X newline(np, 0, cp, 0);
- X np = newname(".mca.r");
- X newline(np, 0, cp, 0);
- X np = newname(".ma.r");
- X newline(np, 0, cp, 0);
- X np = newname(".mo.r");
- X newline(np, 0, cp, 0);
-
- X np = newname(".r");
- X dp = newdep(np, 0);
- X np = newname(".mc");
- X dp = newdep(np, dp);
- X np = newname(".mca");
- X dp = newdep(np, dp);
- X np = newname(".c");
- X dp = newdep(np, dp);
- X np = newname(".ca");
- X dp = newdep(np, dp);
- X np = newname(".ma");
- X dp = newdep(np, dp);
- X np = newname(".mo");
- X dp = newdep(np, dp);
- X np = newname(".o");
- X dp = newdep(np, dp);
- X np = newname(".a");
- X dp = newdep(np, dp);
- X np = newname(".SUFFIXES");
- X newline(np, dp, 0, 0);
- X#endif
- X}
- @//E*O*F rules.c//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo Inspecting for damage in transit...
- temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
- trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
- cat > $temp <<\!!!
- 38 313 1803 README
- 11 22 134 Makefile
- 130 414 2457 h.h
- 115 316 2100 check.c
- 340 1124 6577 input.c
- 156 396 2366 macro.c
- 222 683 4336 main.c
- 452 1202 7682 make.c
- 116 318 1795 reader.c
- 234 740 4819 rules.c
- 1814 5528 34069 total
- !!!
- wc README Makefile h.h check.c input.c macro.c main.c make.c reader.c rules.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
- if test -s $dtemp ; then
- echo "Ouch [diff of wc output]:"
- cat $dtemp
- STATUS=1
- elif test $STATUS = 0 ; then
- echo "No problems found."
- else
- echo "WARNING -- PROBLEMS WERE FOUND..."
- fi
- exit $STATUS
-